package image;

import gui.Main;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.Set;

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.binding.ListBinding;
import javafx.beans.property.ListProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.WritableImage;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;
import static java.lang.Math.random;

/**
 * An ImageCanvas is the class that represents a "file" / "image", which one can draw. It 
 * is typically represented as a tab. 
 * @author Etienne Bruines
 * @author Bas Dobbelsteen
 */
@SuppressWarnings("unused")
public class ImageCanvas 
{
	private int width, height;
	
	/**
	 * The location where the file is stored on the local HDD
	 */
	private String location; 
	
	/**
	 * The title of the image
	 */
	private String title;
	
	private ObjectProperty<Layer> activeProperty;
	
	private ListProperty<Layer> layers;
	
	private Group group;
	// =============
	// Constructors and static-constructors
	// =============
	
	/**
	 * Creates a new, blank ImageCanvas, given width and height
	 * @param w
	 * @param h
	 */
	public ImageCanvas(int w, int h)
	{
		this.width = w;
		this.height = h;
		this.layers = new SimpleListProperty<Layer>(javafx.collections.FXCollections.observableList(new ArrayList<Layer>()));
		this.activeProperty = new SimpleObjectProperty<Layer>(null);
		
		this.layers.addListener(new ListChangeListener<Layer> () {
			@Override public void onChanged(javafx.collections.ListChangeListener.Change<? extends Layer> arg0)
			{
				for (int i = arg0.getList().size() - 1; i >= 0; i--)
				{
					arg0.getList().get(i).getContent().toFront();
				}
			}
		});
		
		this.group = new Group();
//		
//		Rectangle c = new Rectangle(440, 300);
//		c.setSmooth(false);
        
        group.getChildren().add(0, Layer.createBackground(w, h));
	}
	
	private int layerCount = 0;
	
	/**
	 * Opens the file given in our own file format
	 * TODO: opening the file and parsing width / height / layers / etc
	 * @param dir The location to the file
	 * @return
	 */
	public static ImageCanvas openFile(String dir)
	{
		ImageCanvas ic = null;
		// ic.location = dir; 
		return ic;
	}
	
	public void setActiveLayer (int index)
	{
		activeProperty.set( layers.get(index));
	}
	public void setActiveLayer(Layer l )
	{
		activeProperty.set(l);
	}
	
	public Layer getActiveLayer()
	{
		return activeProperty.get();
	}
	
	public ObjectProperty<Layer> activeProperty()
	{
		return activeProperty;
	}
	
	// =============
	// Useful functions
	// =============
	
	/**
	 * Adds Layer l to the list of Layers
	 * @param l
	 */
	public void addLayer(Layer l )
	{
		l.setTitle(++layerCount + " " + l.getTitle());
		layers.add(0, l);
		group.getChildren().add(l.getContent());
	}
	
	/**
	 * Saves file to disk, for later use
	 */
	public void save()
	{
		// TODO: save file to disk
	}
	
	// =============
	// Setters
	// =============
	
	public void setWidth(int w)
	{
		width = w;
	}
	
	public void setHeight(int h)
	{
		height = h;
	}
	
	public void setTitle(String title)
	{
		this.title = title;
	}
	
	public void removeLayer(Layer l )
	{
		this.group.getChildren().remove(l.getContent());
		layers.remove(l);
	}
	
	// =============
	// Getters
	// =============
	
	public int getWidth()
	{
		return width;
	}
	
	public int getHeight()
	{
		return height;
	}
	
	/**
	 * Returns the List of Layers - does not provide a copy (!)
	 * @return
	 */
	public List<Layer> getLayers()
	{
		return layers.get();
	}
	
	@Override public String toString()
	{
		return title;
	}
	// ColorPicker / ensemble
	public Group getGroup()
	{
		return group;
	}
	
	public ListProperty<Layer> layersProperty()
	{
		return layers;
	}
}
